/**   
* @Title: FirstRequestHandler.java 
* @Package net.gdface.httpclient 
* @Description: TODO 
* @author guyadong   
* @date 2015年5月15日 上午8:59:27 
* @version V1.0   
*/
package net.gdface.httpclient;

import java.util.concurrent.ExecutorService;

import net.gdface.utils.Assert;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.util.EntityUtils;

/**
 * 异步请求回调函数对象<br>
 * 当发送一个(图像)请求之前需要先打开引用网页时，使用此对象
 * @author guyadong
 *
 */
public class FirstRequestHandler implements FutureCallback<HttpResponse>,Runnable {
	/**
	 * 请求结束后，要请求的目标
	 */
	private final HttpGet target;
	/**
	 * {@link #target}请求的回调函数对象
	 */
	private final FutureCallback<HttpResponse> callback;
	/**
	 * 当遇到异常时是否忽略<br>
	 * true，不论是否遇到异常，都请求{@link #target}
	 * false, 只有正常获取到数据后才请求{@link #target}
	 */
	private final boolean ignoreFail;
	private final ExecutorService executorService;
	/**
	 * @param target 参见{@link #target}
	 * @param callback 参见{@link #callback}
	 * @param ignoreFail 参见 {@link #ignoreFail}
	 * @param executorService 用于异步发送{@link #target}请求的线程池
	 */
	public FirstRequestHandler(HttpGet target,FutureCallback<HttpResponse> callback,boolean ignoreFail, ExecutorService executorService) {
		super();
		Assert.notNull(target, "target");
		Assert.notNull(callback, "callback");
		this.target = target;
		this.callback=callback;
		this.ignoreFail=ignoreFail;
		this.executorService=executorService;
	}

	@Override
	public void completed(HttpResponse result) {
		try {
			EntityUtils.toString(result.getEntity(), "utf-8");
		} catch (Exception e) {
			if(!ignoreFail)
				return;
		}
		requestTarget();		
	}

	@Override
	public void failed(Exception ex) {
		if(ignoreFail)
			requestTarget();
	}

	@Override
	public void cancelled() {
		if(ignoreFail)
			requestTarget();
		
	}
	
	/**
	 * 异步方式发送请求，减少连接占用
	 */
	private void requestTarget() {
		if(null==executorService)
			new Thread(this).start();
		else{
			executorService.execute(this);
		}
	}

	@Override
	public void run() {
		AsyncClientManager.getInstance().getResponseAsync(target, callback);		
	}
}
